#include <fcntl.h>
#include <ctype.h>
#include "stdint.h"
#include "vfs.h"
#include "if_v.h"
// #include "kv_api.h"
// #include "kv_adapt.h"
// #include "kv_types.h"
#include "ff_mgr.h"
#include "cli_api.h"
#include "aos/kv.h"

#if defined(AOS_COMP_LITTLEFS_PERF)
    #define FF_DIR_PATH FS_ROOT_PATH"/ff"
    #define FF_SDIR_PATH FF_DIR_PATH"/ff_%d"
    #define FF_FILE_PATH "ff_%d"
    #define FF_INFO_PATH FF_DIR_PATH"/ffinfo"
    #define FF_ID2NAME_PATH FF_DIR_PATH"/ffid2name"
#else
    #define FF_DIR_PATH FS_ROOT_PATH"/ff"
    #define FF_FILE_PATH FF_DIR_PATH"/ff"
    #define FF_INFO_PATH FF_DIR_PATH"/ffinfo"
    #define FF_ID2NAME_PATH FF_DIR_PATH"/ffid2name"
#endif

#define FF_CHECK_FIRST_BOOT      "ff_check_first_boot"

#define FF_FILE_NAME_LENGTH 128
#define FF_LOAD_MODE_THRES 500

#if defined(AOS_COMP_FATFS) || defined(AOS_COMP_LITTLEFS)
#define AOS_CONFIG_FF_USE_FS  
#else
#define AOS_CONFIG_FF_USE_KV  
#endif

#if defined(AOS_COMP_LITTLEFS)
#if defined(AOS_COMP_LITTLEFS_PERF)
#define FF_FILE_EACH_SAVE_NUM   5
#define FF_SDIR_EACH_FILE_NUM   10
#else
#define FF_FILE_EACH_SAVE_NUM   20
#endif
#endif

typedef enum ff_err_status {
    FF_OPEN_FILE_ERR   = -1,
    FF_READ_FILE_ERR   = -2,
    FF_WRITE_FILE_ERR  = -3,
    FF_SEEK_FILE_ERR   = -4,
    FF_OPT_SUCCESS     = 0,
} ff_err_status_t;


extern data_flow_func_control_t g_app_flow_cfg;
extern g_variable_control_t g_variable_cfg;
extern uint8_t *faceFeature;
extern uint8_t *faceMaskFeature;


char g_acFfMap[FACE_FEATURE_MAX_NUM] = {0};
char ff_id_str[16] = {0};
// extern kv_item_t *kv_item_traverse(item_func func, uint32_t blk_idx, const char *key);
extern void if_vSaveRgbToFile(uint32_t ulRgbFileIndex);
extern void if_vDelRgbFile(uint32_t ulRgbFileIndex);

static int ff_check_boot_first()
{
    int ff_first_boot_flag=0;
	int len = sizeof(ff_first_boot_flag);
	int ret = aos_kv_get(FF_CHECK_FIRST_BOOT,&ff_first_boot_flag, &len);
    if (ret != 0) 
    {
        printf("get first boot failed\r\n");

    		return -1;
    }else{
    	printf("Get ff first boot is %d\r\n",ff_first_boot_flag);
        if(ff_first_boot_flag)
        	return 0;
        else 
            return -1;

    }
}

static int ff_set_boot_first()
{
    int ff_first_boot_flag=1;
	uint32_t len = sizeof(ff_first_boot_flag);

    int ret = aos_kv_set(FF_CHECK_FIRST_BOOT, &ff_first_boot_flag, len, 1);
    if(ret != 0){
        printf("set ff firt boot failed.");
		return -1;
    }
    else{
        printf("set ff firt boot ok.");
        return 0;
    }
}

int ff_set_boot_nonfirst()
{
    int ff_first_boot_flag=0;
	uint32_t len = sizeof(ff_first_boot_flag);

    int ret = aos_kv_set(FF_CHECK_FIRST_BOOT, &ff_first_boot_flag, len, 1);
    if(ret != 0){
        printf("clear ff firt boot failed.");
		return -1;
    }
    else{
        printf("clear ff firt boot ok.");
        return 0;
    }
}

#if 0
static bool str_is_digit(char *s)
{
	while (*s != '\0') {
		if (!isdigit(*s)) return false;
		else s++;
	}

	return true;
}
#endif

static int is_path_dir(const char *path)
{
    int ret = 0;
    aos_dir_t *dp = aos_opendir(path);

    if (dp) {
        ret = 1;
        aos_closedir(dp);
    }
    //printf("ret %d\n",ret);
    return ret;
}

int check_or_create_dir(const char *path)
{
    int ret;
    
    if(is_path_dir(path)){
        return 0;
    }

    ret = aos_mkdir(path);

    if(ret < 0){
        printf("aos_mkdir [%s] ret=%d\n", path, ret);
        return -1;
    }

    return is_path_dir(path) ? 0 : -1;
}

#if defined(AOS_COMP_LITTLEFS_PERF)
int check_or_create_sdir(void)
{
    int ffile_num = 0;
    int sdir_num = 0;
    char pathTemp[32] = {0};
    char sdirTemp[32] = {0};

    for(ffile_num = 0; ffile_num < FACE_FEATURE_MAX_NUM / FF_FILE_EACH_SAVE_NUM; ffile_num++) {
        if (ffile_num % 10 == 0) {
            memset(sdirTemp, 0, sizeof(pathTemp));
            snprintf(sdirTemp, sizeof(sdirTemp), FF_SDIR_PATH, sdir_num);
            if (check_or_create_dir(sdirTemp) < 0) {
                printf("FaceFeature sdir not exist.\n");
                return -1;
            }   
            sdir_num++;   
        }
    }

    return 0; 
}
#endif

static int ff_load_from_fs(void)
{
#if defined(AOS_COMP_LITTLEFS)
    int ret = FF_OPT_SUCCESS;
    int ff = 0;
    int ffinfo = 0;
	int id = g_variable_cfg.registerIDStartNo;
    uint32_t i, j = 0;
    char ffFilePath[32] = {0};

    ffinfo = aos_open(FF_INFO_PATH, O_RDONLY);
    if (ffinfo < 0) {
        printf("ffinfo file not exit\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }

    ret = aos_read(ffinfo, g_acFfMap, sizeof(g_acFfMap));
    if (ret < 0 || ret != sizeof(g_acFfMap)) {
        printf("read ffinfo error, ret %d\r\n", ret);
        ret = FF_READ_FILE_ERR;
        goto exit;
    }

    for (i = 0; i < FACE_FEATURE_MAX_NUM / FF_FILE_EACH_SAVE_NUM; i++)
    {
        for(j = 0; j < FF_FILE_EACH_SAVE_NUM; j++)
        {
            if (true == g_acFfMap[i * FF_FILE_EACH_SAVE_NUM + j])
            {
#if defined(AOS_COMP_LITTLEFS_PERF)
                memset(ffFilePath, 0, sizeof(ffFilePath));
                snprintf(ffFilePath, sizeof(ffFilePath), FF_SDIR_PATH"/"FF_FILE_PATH, 
                                                            i / FF_SDIR_EACH_FILE_NUM, i);
#else
                memset(ffFilePath, 0, sizeof(ffFilePath));
                snprintf(ffFilePath, sizeof(ffFilePath), "%s_%d", FF_FILE_PATH, i);
#endif                
                ff = aos_open(ffFilePath, O_RDONLY);
                if (ff < 0) {
                    printf("ff file not exit\n");
                    ret = FF_OPEN_FILE_ERR;
                    goto exit;
                }

                ret = aos_read(ff, (uint8_t *)(faceFeature) + i * FF_FILE_EACH_SAVE_NUM * FACE_FEATURE_SIZE , FACE_FEATURE_SIZE * FF_FILE_EACH_SAVE_NUM);
                if (ret < 0 || ret != FACE_FEATURE_SIZE * FF_FILE_EACH_SAVE_NUM) {
                    printf("read ff error, ret %d\r\n", ret);
                    goto exit;
                }

                if (ff) {
                    aos_close(ff);
                    ff = 0;
                }

                break;
            }
        }
    }

    for (i = 0; i < FACE_FEATURE_MAX_NUM; i++)
    {
        if (g_acFfMap[i] == false)
        {
            memset((uint8_t *)faceFeature + i * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);

            if (g_app_flow_cfg.mask_enable)
            {
                memset((uint8_t *)faceMaskFeature + i * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);
            }
        }
    }

exit:
    if (ff) {
        aos_close(ff);
    }
    if (ffinfo) {
        aos_close(ffinfo);
    }

    return ret;
#else
    int ret = FF_OPT_SUCCESS;
    int ff = 0;
    int ffinfo = 0;
	// int id = g_variable_cfg.registerIDStartNo;
    uint32_t ff_cnt = 0;
    uint32_t i = 0;

    ffinfo = aos_open(FF_INFO_PATH, O_RDONLY);
    if (ffinfo < 0) {
        printf("ffinfo file not exit\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ff = aos_open(FF_FILE_PATH, O_RDONLY);
    if (ff < 0) {
        printf("ff file not exit\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_read(ffinfo, g_acFfMap, sizeof(g_acFfMap));
    if (ret < 0 || ret != sizeof(g_acFfMap)) {
        printf("read ffinfo error, ret %d\r\n", ret);
        ret = FF_READ_FILE_ERR;
        goto exit;
    }

    for (i = 0; i < FACE_FEATURE_MAX_NUM; i++)
    {
        if (g_acFfMap[i])
        {
            ff_cnt++;
        }

        if (ff_cnt > FF_LOAD_MODE_THRES)
        {
            break;
        }
    }

    if (ff_cnt > FF_LOAD_MODE_THRES)
    {
        ret = aos_read(ff, (uint8_t *)(faceFeature), FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
        if (ret < 0 || ret != FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) {
            printf("read ff error, ret %d\r\n", ret);
            goto exit;
        }
        
        if (g_app_flow_cfg.mask_enable)
        {
            ret = aos_lseek(ff, FACE_FEATURE_MAX_NUM * FACE_FEATURE_SIZE, SEEK_SET);
            if (ret < 0) {
                printf("mv ff file pos err, maybe ff don't match to ffinfo.\n");
                goto exit;
            }
            ret = aos_read(ff, (uint8_t *)(faceMaskFeature), FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
            if (ret < 0 ) {
                printf("read ff mask error, ret %d\r\n", ret);
                goto exit;
            }
        }

        for (i = 0; i < FACE_FEATURE_MAX_NUM; i++)
        {
            if (g_acFfMap[i] == false)
            {
                memset((uint8_t *)faceFeature + i * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);

                if (g_app_flow_cfg.mask_enable)
                {
                    memset((uint8_t *)faceMaskFeature + i * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);
                }
            }
        }
    }
    else
    {
        memset((uint8_t *)faceFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
        if (g_app_flow_cfg.mask_enable)
        {
            memset((uint8_t *)faceMaskFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
        }
        
        for (int id = 0; id < FACE_FEATURE_MAX_NUM; id++) {
            if (g_acFfMap[id] == true) {
                ret = aos_lseek(ff, id * FACE_FEATURE_SIZE, SEEK_SET);
                if (ret < 0) {
                    printf("mv ff file pos err, maybe ff don't match to ffinfo.\n");
                    goto exit;
                }
                ret = aos_read(ff, (uint8_t *)(faceFeature) + id * FACE_FEATURE_SIZE, FACE_FEATURE_SIZE);
                if (ret < 0 || ret != FACE_FEATURE_SIZE) {
                    printf("read ff file error, ret %d.\n", ret);
                    goto exit;
                }

                if (g_app_flow_cfg.mask_enable)
                {
                    ret = aos_lseek(ff, (id + FACE_FEATURE_MAX_NUM) * FACE_FEATURE_SIZE, SEEK_SET);
                    if (ret < 0) {
                        printf("mv ff file pos err, maybe ff don't match to ffinfo.\n");
                        goto exit;
                    }
                    ret = aos_read(ff, 
                        (uint8_t *)(faceMaskFeature) + id * FACE_FEATURE_SIZE, 
                        FACE_FEATURE_SIZE);
                    if (ret < 0 || ret != FACE_FEATURE_SIZE) {
                        printf("read ff file error, ret %d.\n", ret);
                        goto exit;
                    }
                }
            } 
        }
    }
exit:
    if (ff) {
        aos_close(ff);
    }
    if (ffinfo) {
        aos_close(ffinfo);
    }

    return ret;
#endif
}

static int ff_add_to_fs(uint32_t id, void *pFeature, char flag)
{
    int ret = FF_OPT_SUCCESS;
    int ff = 0;
    int ffinfo = 0;

    ffinfo = aos_open(FF_INFO_PATH, O_RDWR);
    if (ffinfo < 0) {
        printf("ffinfo file not exit(%d)\n", ffinfo);
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }

#if defined(AOS_COMP_LITTLEFS)
    int ffFileId = id / FF_FILE_EACH_SAVE_NUM;
    int ffOffsetId = id % FF_FILE_EACH_SAVE_NUM;
    char ffFilePath[32] = {0};
#if defined(AOS_COMP_LITTLEFS_PERF)
    memset(ffFilePath, 0, sizeof(ffFilePath));
    snprintf(ffFilePath, sizeof(ffFilePath), FF_SDIR_PATH"/"FF_FILE_PATH, 
                                                ffFileId / FF_SDIR_EACH_FILE_NUM, ffFileId);
#else
    memset(ffFilePath, 0, sizeof(ffFilePath));
    snprintf(ffFilePath, sizeof(ffFilePath), "%s_%d", FF_FILE_PATH, ffFileId);
#endif
    ff = aos_open(ffFilePath, O_RDWR);
    if (ff < 0) {
        printf("ff file not exit(%d)\n", ff);
        printf("ff file path(%s)\n", ffFilePath);
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_lseek(ff, ffOffsetId * FACE_FEATURE_SIZE, SEEK_SET);
    if (ret < 0) {
        printf("mv ff file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }
    ret = aos_write(ff, pFeature, FACE_FEATURE_SIZE);
    if (ret < 0 || ret != FACE_FEATURE_SIZE) {
        printf("write ff file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }
#else 
    ff = aos_open(FF_FILE_PATH, O_RDWR);
    if (ff < 0) {
        printf("ff file not exit(%d)\n", ff);
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_lseek(ff, id * FACE_FEATURE_SIZE, SEEK_SET);
    if (ret < 0) {
        printf("mv ff file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }
    ret = aos_write(ff, pFeature, FACE_FEATURE_SIZE);
    if (ret < 0 || ret != FACE_FEATURE_SIZE) {
        printf("write ff file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }
#endif
    ret = aos_lseek(ffinfo, id *sizeof(char), SEEK_SET);
    if (ret < 0) {
        printf("mv ffinfo file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }
    ret = aos_write(ffinfo, &flag, sizeof(char));
    if (ret < 0 || ret != sizeof(char)) {
        printf("write ffinfo file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }

exit:
    if (ff) {
        aos_close(ff);
    }
    if (ffinfo) {
        aos_close(ffinfo);
    }

    return ret;
}

static int ff_add_to_fs_fixed_length(uint32_t id, void *pFeature, char flag, int32_t fixedLength)
{
    int ret = FF_OPT_SUCCESS;
    int ff = 0;
    int ffinfo = 0;
    char flagFixedLength[20] = {0};

    if (fixedLength <= 0 || (fixedLength%5 != 0))
        return -1;

    ffinfo = aos_open(FF_INFO_PATH, O_RDWR);
    if (ffinfo < 0) {
        printf("ffinfo file not exit(%d)\n", ffinfo);
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }

#if defined(AOS_COMP_LITTLEFS)
    int ffFileId = id / FF_FILE_EACH_SAVE_NUM;
    int ffOffsetId = id % FF_FILE_EACH_SAVE_NUM;
    char ffFilePath[32] = {0};
#if defined(AOS_COMP_LITTLEFS_PERF)
    memset(ffFilePath, 0, sizeof(ffFilePath));
    snprintf(ffFilePath, sizeof(ffFilePath), FF_SDIR_PATH"/"FF_FILE_PATH, 
                                                ffFileId / FF_SDIR_EACH_FILE_NUM, ffFileId);
#else
    memset(ffFilePath, 0, sizeof(ffFilePath));
    snprintf(ffFilePath, sizeof(ffFilePath), "%s_%d", FF_FILE_PATH, ffFileId);
#endif
    ff = aos_open(ffFilePath, O_RDWR);
    if (ff < 0) {
        printf("ff file not exit(%d)\n", ff);
        printf("ff file path(%s)\n", ffFilePath);
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_lseek(ff, ffOffsetId * FACE_FEATURE_SIZE, SEEK_SET);
    if (ret < 0) {
        printf("mv ff file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }
    ret = aos_write(ff, pFeature, FACE_FEATURE_SIZE * fixedLength);
    if (ret < 0 || ret != FACE_FEATURE_SIZE * fixedLength) {
        printf("write ff file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }
#else 
    ff = aos_open(FF_FILE_PATH, O_RDWR);
    if (ff < 0) {
        printf("ff file not exit(%d)\n", ff);
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_lseek(ff, id * FACE_FEATURE_SIZE, SEEK_SET);
    if (ret < 0) {
        printf("mv ff file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }
    ret = aos_write(ff, pFeature, FACE_FEATURE_SIZE * fixedLength);
    if (ret < 0 || ret != FACE_FEATURE_SIZE * fixedLength) {
        printf("write ff file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }
#endif
    ret = aos_lseek(ffinfo, id *sizeof(char), SEEK_SET);
    if (ret < 0) {
        printf("mv ffinfo file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }

    memset(flagFixedLength, flag, fixedLength);

    ret = aos_write(ffinfo, flagFixedLength, sizeof(char) * fixedLength);
    if (ret < 0 || ret != sizeof(char) * fixedLength ) {
        printf("write ffinfo file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }

exit:
    if (ff) {
        aos_close(ff);
    }
    if (ffinfo) {
        aos_close(ffinfo);
    }

    return ret;
}

static int ff_delete_from_fs(uint32_t id, char flag)
{
    int ret = FF_OPT_SUCCESS;
    // int ff = 0;
    int ffinfo = 0;
    // char pFeature[FACE_FEATURE_SIZE] = {0xff};

    ffinfo = aos_open(FF_INFO_PATH, O_RDWR);
    if (ffinfo < 0) {
        printf("ff info file not exit\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_lseek(ffinfo, id *sizeof(flag), SEEK_SET);
    if (ret < 0) {
        printf("mv ffinfo file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }
    ret = aos_write(ffinfo, &flag, sizeof(flag));
    if (ret < 0 || ret != sizeof(flag)) {
        printf("write ffinfo file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }

    // ff = aos_open(FF_FILE_PATH, O_RDWR);
    // if (ff < 0) {
    //     printf("ff file not exit\n");
    //     goto exit;
    // }
    // ret = aos_lseek(ff, id * FACE_FEATURE_SIZE, SEEK_SET);
    // if (ret < 0) {
    //     printf("mv ff file pos error.\n");
    //     goto exit;
    // }
    // ret = aos_write(ff, pFeature, FACE_FEATURE_SIZE);
    // if (ret < 0 || ret != FACE_FEATURE_SIZE) {
    //     printf("write ff file error.\n");
    //     goto exit;
    // }

exit:
    if (ffinfo) {
        aos_close(ffinfo);
    }

    // if (ff) {
    //     aos_close(ff);
    // }

    return ret;
}

static int ff_delete_from_fs_fixed_length(uint32_t id, char flag, int32_t fixedLength)
{
    int ret = FF_OPT_SUCCESS;
    // int ff = 0;
    int ffinfo = 0;
    // char pFeature[FACE_FEATURE_SIZE] = {0xff};
    char flagFixedLength[20] = {0};

    ffinfo = aos_open(FF_INFO_PATH, O_RDWR);
    if (ffinfo < 0) {
        printf("ff info file not exit\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_lseek(ffinfo, id *sizeof(flag), SEEK_SET);
    if (ret < 0) {
        printf("mv ffinfo file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }

    memset(flagFixedLength, flag, fixedLength);

    ret = aos_write(ffinfo, flagFixedLength, sizeof(char) * fixedLength);
    if (ret < 0 || ret != sizeof(char) * fixedLength ) {
        printf("write ffinfo file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }

    // ff = aos_open(FF_FILE_PATH, O_RDWR);
    // if (ff < 0) {
    //     printf("ff file not exit\n");
    //     goto exit;
    // }
    // ret = aos_lseek(ff, id * FACE_FEATURE_SIZE, SEEK_SET);
    // if (ret < 0) {
    //     printf("mv ff file pos error.\n");
    //     goto exit;
    // }
    // ret = aos_write(ff, pFeature, FACE_FEATURE_SIZE);
    // if (ret < 0 || ret != FACE_FEATURE_SIZE) {
    //     printf("write ff file error.\n");
    //     goto exit;
    // }

exit:
    if (ffinfo) {
        aos_close(ffinfo);
    }

    // if (ff) {
    //     aos_close(ff);
    // }

    return ret;
}

static int ff_all_delete_from_fs(char *buf, uint32_t len)
{
    int ret = FF_OPT_SUCCESS;
    // int ff = 0;
    int ffinfo = 0;

    ffinfo = aos_open(FF_INFO_PATH, O_RDWR);
    if (ffinfo < 0) {
        printf("ff info file not exit\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    ret = aos_write(ffinfo, buf, len);
    if (ret < 0 || ret != len) {
        printf("read ff file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }

exit:
    if (ffinfo) {
        aos_close(ffinfo);
    }

    return ret;
}

int ff_id2name_add_to_fs(uint32_t id, char *name)
{
    int ret = FF_OPT_SUCCESS;
    int ffid2name = 0;
    int fileNameLen = 0;

    ffid2name = aos_open(FF_ID2NAME_PATH, O_RDWR);
    if (ffid2name < 0) {
        printf("ffid2name file not exit.\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    
    ret = aos_lseek(ffid2name, id * FF_FILE_NAME_LENGTH, SEEK_SET);
    if (ret < 0) {
        printf("mv ffid2name file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }

    fileNameLen = strlen(name);
    fileNameLen = (fileNameLen <= FF_FILE_NAME_LENGTH) ? fileNameLen : FF_FILE_NAME_LENGTH;
    ret = aos_write(ffid2name, name, fileNameLen);
    if (ret < 0 || ret != fileNameLen) {
        printf("write ffid2name file error.\n");
        ret = FF_WRITE_FILE_ERR;
        goto exit;
    }


exit:
    if (ffid2name) {
        aos_close(ffid2name);
    }

    return ret;
}

int ff_id2name_get_from_fs(uint32_t id, char *name)
{
    int ret = FF_OPT_SUCCESS;
    int ffid2name = 0;

    ffid2name = aos_open(FF_ID2NAME_PATH, O_RDWR);
    if (ffid2name < 0) {
        printf("ffid2name file not exit.\n");
        ret = FF_OPEN_FILE_ERR;
        goto exit;
    }
    
    ret = aos_lseek(ffid2name, id * FF_FILE_NAME_LENGTH, SEEK_SET);
    if (ret < 0) {
        printf("mv ffid2name file pos error.\n");
        ret = FF_SEEK_FILE_ERR;
        goto exit;
    }

    ret = aos_read(ffid2name, name, FF_FILE_NAME_LENGTH);
    if (ret < 0 || ret != FF_FILE_NAME_LENGTH) {
        printf("read ffid2name file error.\n");
        ret = FF_READ_FILE_ERR;
        goto exit;
    }

exit:
    if (ffid2name) {
        aos_close(ffid2name);
    }

    return ret;
}

int setIDStartNo(int idStart)
{
	g_variable_cfg.registerIDStartNo = idStart;
    return 0;
}

int getIDStartNo(void)
{
    return g_variable_cfg.registerIDStartNo;
}

/*
return valid feature num
*/
int getValidIDNum(void)
{
    uint32_t id = g_variable_cfg.registerIDStartNo; //
    uint32_t validCount = 0;

    for (; id < FACE_FEATURE_MAX_NUM; id++)
    {
        if (true == g_acFfMap[id])
        {
            validCount++;
        }
    }

    return validCount;
}

/*
idList : input
len    : input
*/
int getValidIDList(uint32_t *idList, uint32_t cnt)
{
    uint32_t id = g_variable_cfg.registerIDStartNo;
	uint32_t validCount = 0;

    if((cnt > FACE_FEATURE_MAX_NUM) || (NULL == idList))
        return -1;

    for (; id < FACE_FEATURE_MAX_NUM; id++)
    {
        if (true == g_acFfMap[id])
        {
            *idList = id;
			printf("[lf]: %d\n", *idList);
			idList++;

			validCount++;
			if(validCount == cnt)
				break;
        }
    }

    return 0;
}

// static int __ff_load_cb(kv_item_t *item, const char *key)
// {
//     kv_size_t off;
//     uint32_t id = 0;
//     char *p_key = NULL;
//     char *p_val = NULL;

//     if (item->hdr.val_len != FACE_FEATURE_SIZE)
//     {
//         return KV_LOOP_CONTINUE;
//     }
    
//     p_key = (char *)kv_malloc(item->hdr.key_len + 1);
//     if (!p_key) {
//         return KV_ERR_MALLOC_FAILED;
//     }

//     memset(p_key, 0, item->hdr.key_len + 1);
//     off = item->pos + KV_ITEM_HDR_SIZE;
//     kv_flash_read(off, p_key, item->hdr.key_len);

//     if (!str_is_digit(p_key))
//     {
//         kv_free(p_key);
//         return KV_LOOP_CONTINUE;
//     }

//     p_val = (char *)kv_malloc(item->hdr.val_len + 1);
//     if (!p_val) {
//         kv_free(p_key);
//         return KV_ERR_MALLOC_FAILED;
//     }

//     memset(p_val, 0, item->hdr.val_len + 1);
//     off = item->pos + KV_ITEM_HDR_SIZE + item->hdr.key_len;
//     kv_flash_read(off, p_val, item->hdr.val_len);

//     id = atoi(p_key);
//     memcpy((uint8_t *)(faceFeature) + id * FACE_FEATURE_SIZE,
//             p_val,
//             FACE_FEATURE_SIZE);
    
//     g_acFfMap[id] = true;
        
//     kv_free(p_key);
//     kv_free(p_val);

//     return KV_LOOP_CONTINUE;
// }

/*  
 *  Face feature initialization function
 *  @param[in] 
 *  @return    0 success other failed
 */
int tsm_ff_load(void)
{
    int ret = 0;
#ifdef AOS_CONFIG_FF_USE_KV   
    for (uint32_t i = 0; i < KV_BLOCK_NUMS; i++) 
    {
        kv_item_traverse(__ff_load_cb, i, NULL);
    }
#elif defined(AOS_CONFIG_FF_USE_FS)
    ret = ff_load_from_fs();    
#endif
    
    return ret;
}

extern uint32_t g_ulIfvDebugEnable;
/*  
 *  Face feature add function
 *  @param[in] pFeature    pointer to the face feature.
 *  @return    ID of face feature
 */
int tsm_ff_add(void *pFeature, void *pMaskFeature)
{
    int32_t id = g_variable_cfg.registerIDStartNo;
	int32_t found_slot = false;
    int32_t retval = 0;

    // 1. Find a extra slot for face feature
    for (; id < FACE_FEATURE_MAX_NUM; id++)
    {
        if (false == g_acFfMap[id])
        {
            found_slot = true;
            break;
        }
    }
    if (false == found_slot)
    {
        cli_printf("No space for extra face feature\r\n");
        return -1;
    }

    // 2. Write face feature to memory
    memcpy(faceFeature + id * FACE_FEATURE_SIZE, pFeature, FACE_FEATURE_SIZE);
	if(g_app_flow_cfg.mask_enable)
    	memcpy(faceMaskFeature + id * FACE_FEATURE_SIZE, pMaskFeature, FACE_FEATURE_SIZE);

#ifdef AOS_CONFIG_FF_USE_KV
    // 3. Write face feature to flash
    itoa(id, ff_id_str);
    retval = aos_kv_set(ff_id_str, pFeature, FACE_FEATURE_SIZE, 1);
    if (retval != 0) 
    {
        cli_printf("Failed to save face feature. retval: %d\r\n", retval);
        return -1;
    }
	if(g_app_flow_cfg.mask_enable){
		itoa(id+FACE_FEATURE_MAX_NUM, ff_id_str);
    	retval = aos_kv_set(ff_id_str, pMaskFeature, FACE_FEATURE_SIZE, 1);
    	if (retval != 0) 
    	{
        	cli_printf("Failed to save face feature. retval: %d\r\n", retval);
        	return -1;
    	}
	}        
#elif defined(AOS_CONFIG_FF_USE_FS)
    retval = ff_add_to_fs(id, pFeature, true);
    if (retval < 0) {
        cli_printf("ff add to fs error.\n");
        return -1;
    }
	
    if(g_app_flow_cfg.mask_enable){
    	retval = ff_add_to_fs(id+FACE_FEATURE_MAX_NUM, pMaskFeature, true);
    	if (retval < 0) {
        	cli_printf("ff add to fs error.\n");
        	return -1;
    	}
    }
#endif    
    g_acFfMap[id] = true;
    
    return id;
}

int tsm_ff_add_fixed_length(void *pFeature, void *pMaskFeature, int32_t fixedLength)
{
    int32_t id = g_variable_cfg.registerIDStartNo;
	int32_t found_slot = false;
    int32_t retval = 0;
    int32_t i = 0;

    if (fixedLength <= 0 || (fixedLength%5 != 0))
        return -1;

    // 1. Find a extra slot for face feature
    for (; id < FACE_FEATURE_MAX_NUM; id++)
    {
        if (false == g_acFfMap[id])
        {
            found_slot = true;
            break;
        }
    }
    if (false == found_slot)
    {
        cli_printf("No space for extra face feature\r\n");
        return -1;
    }

    // 2. Write face feature to memory
    memcpy(faceFeature + id * FACE_FEATURE_SIZE, pFeature, FACE_FEATURE_SIZE * fixedLength);
	if(g_app_flow_cfg.mask_enable)
    	memcpy(faceMaskFeature + id * FACE_FEATURE_SIZE, pMaskFeature, FACE_FEATURE_SIZE * fixedLength);

#ifdef AOS_CONFIG_FF_USE_KV
    // 3. Write face feature to flash
    itoa(id, ff_id_str);
    retval = aos_kv_set(ff_id_str, pFeature, FACE_FEATURE_SIZE, 1);
    if (retval != 0) 
    {
        cli_printf("Failed to save face feature. retval: %d\r\n", retval);
        return -1;
    }
	if(g_app_flow_cfg.mask_enable){
		itoa(id+FACE_FEATURE_MAX_NUM, ff_id_str);
    	retval = aos_kv_set(ff_id_str, pMaskFeature, FACE_FEATURE_SIZE, 1);
    	if (retval != 0) 
    	{
        	cli_printf("Failed to save face feature. retval: %d\r\n", retval);
        	return -1;
    	}
	}        
#elif defined(AOS_CONFIG_FF_USE_FS)
    retval = ff_add_to_fs_fixed_length(id, pFeature, true, fixedLength);
    if (retval < 0) {
        cli_printf("ff add to fs error.\n");
        return -1;
    }
	
    if (g_app_flow_cfg.mask_enable){
    	retval = ff_add_to_fs_fixed_length(id+FACE_FEATURE_MAX_NUM, pMaskFeature, true, fixedLength);
    	if (retval < 0) {
        	cli_printf("ff add to fs error.\n");
        	return -1;
    	}
    }
#endif
    for (i = 0; i < fixedLength; i++)
        g_acFfMap[id+i] = true;
    
    return id;
}

/*  
 *  Face feature get function
 *  @param[in] id          ID of face feature.
 *  @param[in] pFeature    pointer to the face feature.
 */
int tsm_ff_get(uint32_t id, void *feature)
{
    memcpy(feature, faceFeature + id * FACE_FEATURE_SIZE, FACE_FEATURE_SIZE);
    return 0;
}

/*  
 *  Face feature delete function
 *  @param[in] id          ID of face feature.
 *  @return    0 success other failed
 */
int tsm_ff_delete(uint32_t id)
{
    int32_t retval = 0;

	if(id < g_variable_cfg.registerIDStartNo)
		return -1;

    // 1. Zero face feature zone in memory
    memset(faceFeature + id * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);
	if(g_app_flow_cfg.mask_enable)
    	memset(faceMaskFeature + id * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);

#ifdef AOS_CONFIG_FF_USE_KV
    // 2. Delete face feature in flash
    itoa(id, ff_id_str);
    retval = aos_kv_del(ff_id_str);
	if(g_app_flow_cfg.mask_enable){
    	itoa(id+FACE_FEATURE_MAX_NUM, ff_id_str);
    	retval = aos_kv_del(ff_id_str);
	}
#elif defined(AOS_CONFIG_FF_USE_FS)
    retval = ff_delete_from_fs(id, false);
    if (retval < 0) {
        printf("delete ff from fs error.\n");
        return retval;
    }

	if(g_app_flow_cfg.mask_enable){
    	retval = ff_delete_from_fs(id+FACE_FEATURE_MAX_NUM, false);
    	if (retval < 0) {
            printf("delete mask ff from fs error.\n");
            return retval;
    	}
	}
#endif
    // 3. Clear flag for this face feature
    g_acFfMap[id] = false;

    return retval;
}

int tsm_ff_delete_fixed_length(uint32_t id, int32_t fixedLength)
{
    int32_t retval = 0;
    int32_t i = 0;

    if (fixedLength <= 0 || (fixedLength%5 != 0)) {
        return -1;
    }

	if(id < g_variable_cfg.registerIDStartNo) {
		return -1;
    }

    // 1. Zero face feature zone in memory
    memset(faceFeature + id * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE * fixedLength);
	if(g_app_flow_cfg.mask_enable)
    	memset(faceMaskFeature + id * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE * fixedLength);

#ifdef AOS_CONFIG_FF_USE_KV
    // 2. Delete face feature in flash
    itoa(id, ff_id_str);
    retval = aos_kv_del(ff_id_str);
	if(g_app_flow_cfg.mask_enable){
    	itoa(id+FACE_FEATURE_MAX_NUM, ff_id_str);
    	retval = aos_kv_del(ff_id_str);
	}
#elif defined(AOS_CONFIG_FF_USE_FS)
    retval = ff_delete_from_fs_fixed_length(id, false, fixedLength);
    if (retval < 0) {
        printf("delete ff from fs error.\n");
        return retval;
    }

	if(g_app_flow_cfg.mask_enable){
    	retval = ff_delete_from_fs_fixed_length(id+FACE_FEATURE_MAX_NUM, false, fixedLength);
    	if (retval < 0) {
            printf("delete mask ff from fs error.\n");
            return retval;
    	}
	}
#endif
    // 3. Clear flag for this face feature
    for (i = 0; i < fixedLength; i++)
        g_acFfMap[id+i] = false;

    return retval;
}

/*  
 *  Face feature clear function
 *  @return    0 success other failed
 */
int tsm_ff_clear(void)
{
    int32_t retval = 0;
    // int fd = 0;
    // int ret = 0;
    
    // 1. Zero face feature zone in memory
    //memset(FACE_FEATURE_MEM_BASEADDR, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
#ifdef AOS_CONFIG_FF_USE_KV 
	uint32_t id = g_variable_cfg.registerIDStartNo;
    for (; id < FACE_FEATURE_MAX_NUM; id++)
    {
        if (true == g_acFfMap[id])
        {
            // 2. Delete face feature in flash
            itoa(id, ff_id_str);
            retval = aos_kv_del(ff_id_str);
            if (retval < 0)
            {
                return retval;
            }
            
            // 3. Clear flag for this face feature
            g_acFfMap[id] = false;
            if_vDelRgbFile(id);
        }
    }
#elif defined(AOS_CONFIG_FF_USE_FS)
    // uint32_t ff_cnt = 0;

    // for (uint32_t i = 0; i < FACE_FEATURE_MAX_NUM; i++)
    // {
    //     if (g_acFfMap[i])
    //     {
    //         ff_cnt++;
    //     }

    //     if (ff_cnt > FF_LOAD_MODE_THRES)
    //     {
    //         break;
    //     }
    // }

    // fd = aos_open(FF_FILE_PATH, O_RDWR);
    // if(fd < 0){
    //     printf("aos_open [%s] ret=%d\n", FF_FILE_PATH, fd);
    //     retval -1;
    // }
    // if (ff_cnt > FF_LOAD_MODE_THRES)
    // {
    //     memset((uint8_t *)faceFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
    //     if(aos_write(fd, faceFeature, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) 
    //         != FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) {
    //         retval = -1;
    //         printf("init ffinfo write to file error.\n");
    //     }
    //     if (g_app_flow_cfg.mask_enable)
    //     {
    //         memset((uint8_t *)faceMaskFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
    //         retval = aos_lseek(fd, FACE_FEATURE_MAX_NUM * FACE_FEATURE_SIZE, SEEK_SET);
    //         if (retval < 0) {
    //             printf("mv ff file pos err, maybe ff don't match to ffinfo.\n");
    //             retval = -1;
    //         }
    //         if(aos_write(fd, faceMaskFeature, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) 
    //             != FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) {
    //             retval = -1;
    //             printf("init ffinfo write to file error.\n");
    //         }
    //     }
    // }
    // else
    // {
    //     for (int id = 0; id < FACE_FEATURE_MAX_NUM; id++) {
    //         if (g_acFfMap[id] == true) 
    //         {
    //             memset((uint8_t *)faceFeature + id * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);
    //            
    //             ret = aos_lseek(fd, id * FACE_FEATURE_SIZE, SEEK_SET);
    //             if (ret < 0) {
    //                 printf("mv ff file pos err, maybe ff don't match to ffinfo.\n");
    //             }

    //             ret = aos_write(fd, faceFeature + id * FACE_FEATURE_SIZE, FACE_FEATURE_SIZE);
    //             if (ret < 0 || ret != FACE_FEATURE_SIZE) {
    //                 printf("write ff file error.\n");
    //                 ret = FF_WRITE_FILE_ERR;
    //             }
                
    //             if (g_app_flow_cfg.mask_enable)
    //             {
    //                 memset((uint8_t *)faceMaskFeature + id * FACE_FEATURE_SIZE, 0xff, FACE_FEATURE_SIZE);
                    
    //                 ret = aos_lseek(fd, (id + FACE_FEATURE_MAX_NUM) * FACE_FEATURE_SIZE, SEEK_SET);
    //                 if (ret < 0) {
    //                     printf("mv ff file pos err, maybe ff don't match to ffinfo.\n");
    //                 }
                    
    //                 ret = aos_write(fd, faceMaskFeature + id * FACE_FEATURE_SIZE, FACE_FEATURE_SIZE);
    //                 if (ret < 0 || ret != FACE_FEATURE_SIZE) {
    //                     printf("write ff file error.\n");
    //                     ret = FF_WRITE_FILE_ERR;
    //                 }
    //             }
    //         } 
    //     }
    // }
    // if (fd) 
    // {
    //     aos_close(fd);
    // }
    
    memset((uint8_t *)faceFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
    if (g_app_flow_cfg.mask_enable)
    {
        memset((uint8_t *)faceMaskFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
    }

    memset(g_acFfMap, 0x0, sizeof(g_acFfMap));
    retval = ff_all_delete_from_fs(g_acFfMap, sizeof(g_acFfMap));
    if (retval < 0) {
        printf("delete all ff from fs error.\n");
    }
#endif
    return retval;
}

/*  
 *  Face feature id dump function
 */
int tsm_ff_dump_id(void)
{
	uint32_t id = g_variable_cfg.registerIDStartNo;
    cli_printf("Face feature ID list: \r\n[");
    for (; id < FACE_FEATURE_MAX_NUM; id++)
    {
        if (true == g_acFfMap[id])
        {
            cli_printf(" %d ", id);
        }
    }
    cli_printf("]\r\n");

    return 0;
}

static int is_file_exit(const char *path)
{
    int ret = 0;
    int fd = aos_open(path, O_RDONLY);

    if (fd >= 0) {
        ret = 1;
        aos_close(fd);
    }

    return ret;
}


static int check_or_create_file(const char *path)
{
#if defined(AOS_COMP_LITTLEFS)
    int fd = 0;
    int ret = 0;
    int i = 0;
    char pathTemp[32] = {0};

    if (!strcmp(FF_FILE_PATH, path))
    {
        //暂定第一个文件存在就算通过
#if defined(AOS_COMP_LITTLEFS_PERF)
        memset(pathTemp, 0, sizeof(pathTemp));
        snprintf(pathTemp, sizeof(pathTemp), FF_SDIR_PATH"/"FF_FILE_PATH, 
                                                0, 0);
#else
        memset(pathTemp, 0, sizeof(pathTemp));
        snprintf(pathTemp, sizeof(pathTemp), "%s_0", FF_FILE_PATH);
#endif      
        if(is_file_exit(pathTemp)){
            printf("%s:ff file path exist\n", __func__);
            return 0;
        } 

        printf("create or re-create %s file.\n", FF_FILE_PATH);
        
        memset((uint8_t *)faceFeature, 0xff, FACE_FEATURE_SIZE * FF_FILE_EACH_SAVE_NUM);
        
        for(i = 0; i < FACE_FEATURE_MAX_NUM / FF_FILE_EACH_SAVE_NUM; i++) {
            //确定路径名
#if defined(AOS_COMP_LITTLEFS_PERF)
            memset(pathTemp, 0, sizeof(pathTemp));
            snprintf(pathTemp, sizeof(pathTemp), FF_SDIR_PATH"/"FF_FILE_PATH, 
                                                    i/FF_SDIR_EACH_FILE_NUM, i);
#else
            memset(pathTemp, 0, sizeof(pathTemp));
            snprintf(pathTemp, sizeof(pathTemp), "%s_%d", FF_FILE_PATH, i);
#endif            
            //open
            fd = aos_open(pathTemp, O_RDWR | O_CREAT);
            if(fd < 0){
                printf("aos_open [%s] ret=%d\n", pathTemp, fd);
                ret -1;
                goto exit;
            }

            //write
            if(aos_write(fd, faceFeature, FACE_FEATURE_SIZE * FF_FILE_EACH_SAVE_NUM) 
                != FACE_FEATURE_SIZE * FF_FILE_EACH_SAVE_NUM){
                ret = -1;
                printf("init ffinfo write to file error.\n");
                goto exit;
            }

            //close
            if (fd) {
                aos_close(fd);
                fd = 0;
            }
        }
    }
    else if (!strcmp(FF_INFO_PATH, path))
    {
        if(is_file_exit(path)){
            return 0;
        } 
        printf("create or re-create %s file.\n", path);
        fd = aos_open(path, O_RDWR | O_CREAT);
        if(fd < 0){
            printf("aos_open [%s] ret=%d\n", path, fd);
            ret -1;
            goto exit;
        }

        memset(g_acFfMap, 0x0, sizeof(g_acFfMap));
        if(aos_write(fd, g_acFfMap, sizeof(g_acFfMap)) != sizeof(g_acFfMap)) {
            ret = -1;
            printf("init ffinfo write to file error.\n");
			goto exit;
        }
    }
    else
        return 0;

exit:
    if (fd) {
        aos_close(fd);
        fd = 0;
    }
	
    return ret;
#else
    int fd = 0;
    int ret = 0;
    
    if(is_file_exit(path)){
        return 0;
    } 
    printf("create or re-create %s file.\n", path);
    fd = aos_open(path, O_RDWR | O_CREAT);
    if(fd < 0){
        printf("aos_open [%s] ret=%d\n", path, fd);
        ret = -1;
        goto exit;
    }
    if (!strcmp(FF_FILE_PATH, path))
    {
        memset((uint8_t *)faceFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
        if(aos_write(fd, faceFeature, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) 
            != FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) {
            ret = -1;
            printf("init ffinfo write to file error.\n");
			goto exit;
        }

        if (g_app_flow_cfg.mask_enable)
        {
            memset((uint8_t *)faceMaskFeature, 0xff, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM);
            ret = aos_lseek(fd, FACE_FEATURE_MAX_NUM * FACE_FEATURE_SIZE, SEEK_SET);
            if (ret < 0) {
                printf("mv ff file pos err, maybe ff don't match to ffinfo.\n");
                ret = -1;
				goto exit;
            }
            if(aos_write(fd, faceMaskFeature, FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) 
                != FACE_FEATURE_SIZE * FACE_FEATURE_MAX_NUM) {
                ret = -1;
                printf("init ffinfo write to file error.\n");
				goto exit;
            }
        }
    }
    else if (!strcmp(FF_INFO_PATH, path))
    {
        memset(g_acFfMap, 0x0, sizeof(g_acFfMap));
        if(aos_write(fd, g_acFfMap, sizeof(g_acFfMap)) != sizeof(g_acFfMap)) {
            ret = -1;
            printf("init ffinfo write to file error.\n");
			goto exit;
        }
    }
exit:
    if (fd) {
        aos_close(fd);
    }
	
    return is_file_exit(path) ? ret : -1;
#endif
}

int create_ff_dir_and_files(void)
{

    if(!ff_check_boot_first())  return 0;

   if (check_or_create_dir(FF_DIR_PATH) < 0){
        printf("FaceFeature dir not exist.\n");
        return -1;
    }
#if defined(AOS_COMP_LITTLEFS_PERF)
    if (check_or_create_sdir() < 0) {
        printf("FaceFeature subdir not exist.\n");
        return -1;
    }
#endif    
    if (check_or_create_file(FF_FILE_PATH) < 0) {
        printf("ff file not exist.\n");
        return -1;
    }
    if (check_or_create_file(FF_INFO_PATH) < 0) {
        printf("%s:file not exist.\n", FF_INFO_PATH);
        return -1;
    }

    if (check_or_create_file(FF_ID2NAME_PATH) < 0) {
        printf("%s:file not exist.\n", FF_ID2NAME_PATH);
        return -1;
    }

    ff_set_boot_first();
    return 0;
} 


